<template>
  <main-card title="算法开发" :tabs="getTabs()" :online-lab="true" :show-screen-space="false">
    <template #tool-btn><a-button type="primary" @click="router.push('/algo-dev/notebook/add')">创建NoteBook </a-button> </template>
    <div class="mb-32 fbc">
      <a-select v-model:value="pageForm.status" class="w-140" :options="statusOptions" @change="getDataList({ offset: 1 })" />
      <a-input
        v-model:value="pageForm.name"
        v-trim
        class="h-36"
        allow-clear
        placeholder="请输入名称"
        style="width: 268px"
        @keyup.enter="getDataList({ offset: 1 })"
      >
        <template #prefix> <i class="iconfont icon-search-line"></i> </template>
      </a-input>
    </div>
    <a-table
      :style="{ width: '100%' }"
      :columns="tableColumns"
      :data-source="dataList"
      :pagination="false"
      :loading="loading || startLoading"
      :custom-row="r => ({ onClick: () => handleToDetail(r) })"
      @change="onTableChange"
    >
      <template #bodyCell="{ column, record }">
        <div v-if="column.dataIndex === 'status'" class="flex items-center">
          <span v-if="[5, 6].includes(record.status)" class="error-mark"></span>
          {{ statusOptions.find(item => item.value === record.status)?.label }}
          <span v-if="[1, 2, 3].includes(record.status)">..</span>
        </div>
        <template v-else-if="column.dataIndex == 'cpu'">
          <div class="noun">
            <span>CPU:{{ record.cpu }}Core</span>
            <span class="mid-line"></span>
            <span>内存:{{ record.memory }}GB</span>
            <span class="mid-line"></span>
            <span>显存:{{ record.gpu }}GB</span>
          </div>
        </template>
        <template v-else-if="column.dataIndex == 'createTime'">
          <div>
            {{ dateFormat(record.createTime) }}
          </div>
        </template>

        <template v-else-if="column.dataIndex === 'tools'">
          <a-dropdown placement="bottom" @click.stop>
            <a-button :data-share="record?.createType === 1" type="text" class="icon-only-btn" @click.stop>
              <i class="iconfont icon-more-line"></i>
            </a-button>
            <template #overlay>
              <a-menu>
                <a-menu-item
                  v-if="checkPermissions(record?.createType, record?.readOnly)"
                  class="menu-icon-item"
                  @click="editMirror(record as NotebookType)"
                >
                  编辑
                </a-menu-item>
                <a-menu-item
                  v-if="checkPermissions(record?.createType, record?.readOnly) && record.status === 3"
                  class="menu-icon-item"
                  @click="openItem(record as NotebookType)"
                >
                  打开
                </a-menu-item>
                <a-menu-item
                  v-if="checkPermissions(record?.createType, record?.readOnly) && [1, 2, 3, 5, 6].includes(record.status)"
                  class="menu-icon-item"
                  @click="operateStatus(record as NotebookType)"
                >
                  {{ [1, 2, 3].includes(record.status) ? '停止' : '启动' }}
                </a-menu-item>
                <a-menu-item v-if="[3, 5].includes(record.status)" class="menu-icon-item" @click="saveAlgo(record as NotebookType)">
                  保存
                </a-menu-item>
                <a-menu-item
                  v-if="checkPermissions(record?.createType, record?.readOnly) && [1, 2, 3, 6, 5].includes(record.status)"
                  class="menu-icon-item"
                  @click="openDeleteModal(record as NotebookType)"
                >
                  删除
                </a-menu-item>
                <a-menu-item
                  v-if="checkPermissions(record?.createType, record?.readOnly)"
                  class="menu-icon-item"
                  @click="handleOpenShareModal(record as NotebookType)"
                >
                  分享
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </template>
        <template v-else> {{ replaceEmptyStr(record[column.dataIndex as string]) }} </template>
      </template>
    </a-table>
    <g-pagination v-model:offset="pageForm.offset" v-model:limit="pageForm.limit" :total="pageForm.total" @change="getDataList" />
  </main-card>
  <share-modal
    ref="shareModalRef"
    :submit-api="algoDevApi.shareNotebook"
    :remove-user-api="algoDevApi.removeNotebookShareUser"
    :get-list-api="algoDevApi.getNotebookShareList"
  />
  <delete-confirm-dialog
    v-model:show="showDeleteModal"
    title="确认删除"
    msg="NoteBook删除后，不可恢复，请确认操作"
    label="请输入NoteBook名称"
    :confirm-name="selectItem?.name"
    :loading="confirmLoading"
    @ok="onOkDeleteTask"
  />
  <detail-modal ref="detailRef" />
  <edit-modal ref="editModalRef" :after-close-fn="getDataList" />
  <save-algo-modal ref="saveAlgoModalRef" :after-close-fn="getDataList" />
</template>

<script setup lang="ts">
  import { message, Modal } from 'ant-design-vue'
  import { dateFormat, isEqual } from 'g6-fn'
  import { onUnmounted, ref } from 'vue'
  import { useRequest } from 'vue-request'
  import { useRouter } from 'vue-router'

  import GPagination from '@/components/GPagination/index.vue'
  import MainCard from '@/components/MainCard/index.vue'
  import ShareModal from '@/components/ShareModal/index.vue'
  import useList from '@/hooks/use-list'
  import { algoDevApi } from '@/services/api'
  import { filterTableColumns, replaceEmptyStr } from '@/utils'
  import { checkPermissions } from '@/utils/share'

  import { useOpenNotebook } from '../../hooks/use-open-notebook'
  import { getTabs } from '../../utils'
  import DetailModal from '../components/detailModal.vue'
  import EditModal from '../components/editModal.vue'
  import SaveAlgoModal from '../components/saveAlgoModal.vue'
  import { NotebookType } from '../types/index'

  const router = useRouter()
  const useNotebook = useOpenNotebook(1)

  interface PageForm {
    name: string
    /**
     * 构建状态（1创建中 2启动中 3运行中 4停止中 5停止 6异常）
     */
    status: 1 | 2 | 3 | 4 | 5 | 6 | ''
    columns: 'updateTime' | 'createTime'
    order: 'desc' | 'asc'
  }

  // 类型
  const statusOptions = [
    {
      label: '全部状态',
      value: ''
    },
    {
      label: '创建中',
      value: 1
    },
    {
      label: '启动中',
      value: 2
    },
    {
      label: '运行中',
      value: 3
    },
    {
      label: '已停止',
      value: 5
    },
    {
      label: '异常',
      value: 6
    }
  ]

  // 表格
  const tableColumns = ref(
    filterTableColumns([
      {
        title: '名称',
        dataIndex: 'name',
        width: 180
      },
      {
        title: '资源配置',
        dataIndex: 'cpu',
        width: 300
      },
      {
        title: '描述',
        dataIndex: 'remark'
      },
      {
        title: '状态',
        dataIndex: 'status',
        width: 120
      },
      {
        title: '创建时间',
        dataIndex: 'createTime',
        isSort: true,
        width: 200
      },
      {
        title: '操作',
        width: 60,
        dataIndex: 'tools'
      }
    ])
  )

  const saveAlgoModalRef = ref()
  const saveAlgo = (item: NotebookType) => {
    saveAlgoModalRef.value.open(item.id)
  }

  const openItem = (item: NotebookType) => {
    useNotebook.checkNotebookStatus(item.id, item.serviceUrl)
  }

  /* 详情逻辑 ---------------------------------------------------------------------*/
  const detailRef = ref()
  const handleToDetail = async (item: NotebookType) => {
    detailRef.value.open(item.id)
  }

  /* 启停逻辑 ---------------------------------------------------------------------*/
  let stopModal: any = null
  const { loading: startLoading, runAsync: runStartNotebook } = useRequest(algoDevApi.startNotebook)
  const { loading: stopLoading, runAsync: runStopNotebook } = useRequest(algoDevApi.stopNotebook, {
    onBefore: () => {
      stopModal?.update({
        okButtonProps: { loading: stopLoading.value }
      })
    },
    onAfter: () => {
      stopModal?.update({
        okButtonProps: { loading: stopLoading.value }
      })
    }
  })
  const operateStatus = async (item: NotebookType) => {
    // 启动任务
    if (item.status === 5 || item.status === 4 || item.status === 6) {
      await runStartNotebook({}, { urlParams: { id: item?.id } })
      message.success('操作成功')
      getDataList()
      return
    }
    // 停止任务
    stopModal = Modal.confirm({
      title: `此Notebook将被停止，请确认操作`,
      centered: true,
      okButtonProps: { loading: stopLoading.value },
      async onOk() {
        await runStopNotebook({}, { urlParams: { id: item?.id } })
        message.success('操作成功')
        getDataList()
      }
    })
  }

  /* 编辑逻辑 ---------------------------------------------------------------------*/
  const editModalRef = ref()
  const editMirror = (item: NotebookType) => {
    let params = {
      id: item.id,
      name: item.name,
      remark: item.remark
    }
    editModalRef.value.open(params)
  }

  /* 分享逻辑 ---------------------------------------------------------------------*/
  const shareModalRef = ref()
  const handleOpenShareModal = (item: NotebookType) => {
    shareModalRef.value?.open({
      id: item.id
    })
  }

  /* 删除逻辑 ---------------------------------------------------------------------*/
  const selectItem = ref<NotebookType>() //当前选中的应用
  const showDeleteModal = ref(false)
  const openDeleteModal = async (item: NotebookType) => {
    selectItem.value = item
    showDeleteModal.value = true
  }

  const { loading: confirmLoading, runAsync: runDel } = useRequest(algoDevApi.delNotebook)
  const onOkDeleteTask = async () => {
    await runDel({}, { urlParams: { id: selectItem.value?.id } })
    message.success('操作成功')
    showDeleteModal.value = false
    getDataList()
  }

  /* 列表 ---------------------------------------------------------------------*/
  const { pageForm, dataList, getDataList, loading } = useList<PageForm, NotebookType>(algoDevApi.notebookList, {
    status: '',
    name: '',
    columns: 'createTime',
    order: 'desc'
  })

  const onTableChange = (pagination: any, filters: any, sorter: any) => {
    if (!sorter.order) {
      getDataList({ order: 'desc', columns: 'createTime' })
      return
    }
    const order = sorter.order === 'ascend' ? 'asc' : 'desc'
    getDataList({ offset: 1, order, columns: sorter.field })
  }
  getDataList()

  /* 3s更新一次列表数据，主要用于更新数据状态 ---------------------------------------------------------------------*/
  let getListTimer: any = null
  const getDataListTimer = () => {
    getListTimer = setInterval(async () => {
      let res = await algoDevApi.notebookList(pageForm.value)
      let timerData = res.data.records
      // timer获取的数据id和列表数据保持一直时 更新列表
      let timerDataIds = timerData.map((item: NotebookType) => item.id)
      let dataListIds = dataList.value.map((item: NotebookType) => item.id)
      if (isEqual(timerDataIds, dataListIds)) {
        dataList.value = timerData
      }
    }, 3000)
  }
  getDataListTimer()

  onUnmounted(() => {
    clearInterval(getListTimer)
  })
</script>
<style lang="less" scoped>
  .error-mark {
    margin-right: 6px;
    width: 6px;
    height: 6px;
    background-color: @danger;
    border-radius: 50%;
  }

  .noun {
    display: flex;
    align-items: center;

    .mid-line {
      display: inline-block;
      margin: 0 4px;
      width: 1px;
      height: 14px;
      background-color: #e8e9eb;
    }
  }
</style>
